package com.ketti.team;

import android.content.Context;
import android.text.InputType;
import android.text.Selection;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewStub;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class SourceView extends RelativeLayout {
	
	public int tabNumber;
	private int IndicatorLocation;
	
	private NewEditText newSourceView;
	
	private View 		searchBox;
	private Button 		searchBoxButton;
	private EditText 	searchBoxEdit;
	private CheckBox 	searchBoxCheck;
	private ImageView 	searchIndicator;
	
	private View 		tabMenu;
	private Button 		tabMenuNewButton;
	private Button 		tabMenuOpenButton;
	private Button 		tabMenuSaveButton;
	private Button 		tabMenuCloseButton;	
	private ImageView 	menuIndicator;
	
	
	private int preSearchStart = 0;
	private int preSearchCount = 0;
	private String preSearchString = "";
	private InputMethodManager inputMethodManager;	
	private String fileName;
	
	private Animation pushTopIn;
	
	
	
	public NewEditText getNewSouceView(){
		return newSourceView;
	}

	public SourceView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public SourceView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public SourceView(Context context) {
		super(context);
		String inflaterService = Context.LAYOUT_INFLATER_SERVICE;
		LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(inflaterService);
		layoutInflater.inflate(R.layout.source_view, this, true);		
		
		newSourceView 	= (NewEditText) 	findViewById(R.id.source_editor);
		newSourceView.setSourceView(this);
		
//		searchBoxEdit.setImeOptions(EditorInfo.IME_ACTION_DONE);
		

//		FileIO fileio = new FileIO();
//		newSourceView.setText(fileio.readFile("/sdcard/source/", "Setting.java"));
		newSourceView.setTextSize(Setting.getmFontSize());
		newSourceView.setGravity(Gravity.TOP);
		newSourceView.setHorizontallyScrolling(true);	
		pushTopIn = AnimationUtils.loadAnimation(getContext(), R.anim.push_top_in);
	}
	
	public void setFileName(String filename){
		fileName = filename;
	}
	
	public void setSource(){
		if(fileName != null){
			FileIO fileio = new FileIO();
			newSourceView.setText(fileio.readFile("/sdcard/source/", fileName));
		}
	}
	
	/* control search box's visible state. if searchBox is null, find and inflate*/
	public void controlSearchBox(){
		if(searchBox == null){			
    		searchBox = ((ViewStub) findViewById(R.id.search_box_layout)).inflate();  
    		IndicatorLocation = (getMeasuredWidth()/((EditorActivity.sTabCount+1)*2))*(tabNumber*2 + 1);    		
    		findSearchBoxComponentAndHookUp();
    		}	
		if(tabMenu != null && tabMenu.getVisibility() == View.VISIBLE)
			tabMenu.setVisibility(View.GONE);
		searchBox.setVisibility(searchBox.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
		if(searchBox.getVisibility() == View.VISIBLE)
			searchBox.startAnimation(pushTopIn);
	}
	
	public void controlTabMenu(){
		if(tabMenu == null){
			tabMenu = ((ViewStub) findViewById(R.id.tab_menu_layout)).inflate();
			IndicatorLocation = (getMeasuredWidth()/((EditorActivity.sTabCount+1)*2))*(tabNumber*2 + 1);
    		findTabMenuCompoentAndHookUp();
			}			   
    		
		if(searchBox != null && searchBox.getVisibility() == View.VISIBLE)
			searchBox.setVisibility(View.GONE);
		tabMenu.setVisibility(tabMenu.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
		if(tabMenu.getVisibility() == View.VISIBLE)
			tabMenu.startAnimation(pushTopIn);
	}
	
	public void findTabMenuCompoentAndHookUp(){
		tabMenuNewButton 	= (Button) findViewById(R.id.tabmenu_box_new);
		tabMenuOpenButton	= (Button) findViewById(R.id.tabmenu_box_open);
		tabMenuSaveButton	= (Button) findViewById(R.id.tabmenu_box_save);
		tabMenuCloseButton	= (Button) findViewById(R.id.tabmenu_box_close);
		menuIndicator 		= (ImageView)		findViewById(R.id.tabmenu_tri_indicator);
		
		tabMenuNewButton.setTextSize(Setting.getmFontSize());
		tabMenuOpenButton.setTextSize(Setting.getmFontSize());
		tabMenuSaveButton.setTextSize(Setting.getmFontSize());
		tabMenuCloseButton.setTextSize(Setting.getmFontSize());
		
		menuIndicator.setPadding(IndicatorLocation, getPaddingTop(), getPaddingRight(), getPaddingBottom());
	}
	
	/**
	 * find components and hook up with click listener
	 * this method will be called in "newSourceView" 
	 **/
	public void findSearchBoxComponentAndHookUp() {
		
		searchBoxButton = (Button) 			findViewById(R.id.search_box_button);
		searchBoxEdit	= (EditText)		findViewById(R.id.search_box_edit);
		searchBoxCheck	= (CheckBox)		findViewById(R.id.search_box_check);
		searchIndicator = (ImageView)		findViewById(R.id.search_tri_indicator);
		
		searchBoxButton.setTextSize(Setting.getmFontSize());
		searchBoxEdit.setTextSize(Setting.getmFontSize());	
		searchIndicator.setPadding(IndicatorLocation, getPaddingTop(), getPaddingRight(), getPaddingBottom());
		
		searchBoxButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {	
				
				// if there's no string in searchBoxEdit, toast a message
				if(searchBoxEdit.length() == 0){
					if(!(searchBoxCheck.isChecked())){
						Toast toast = Toast.makeText(getContext(), "Please enter some text to search", Toast.LENGTH_SHORT);
						toast.setGravity(Gravity.TOP, 0, 150);
						toast.show();
					}
					else{
						Toast toast = Toast.makeText(getContext(), "Please enter some number to go line", Toast.LENGTH_SHORT);
						toast.setGravity(Gravity.TOP, 0, 150);
						toast.show();
					}				
				}
				else{
					if(!(searchBoxCheck.isChecked()))
						searchWithString();				
					else
						searchWithLineNumber();
				}															
			}
		});
		
		searchBoxCheck.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				if(isChecked == true){
					searchBoxButton.setText("Line");
					searchBoxEdit.setHint("Type to Go Line");
					searchBoxEdit.setText("");
					searchBoxEdit.setInputType(InputType.TYPE_CLASS_PHONE);
				}					
				else{
					searchBoxButton.setText("Search");
					searchBoxEdit.setHint("Type to Search");
					searchBoxEdit.setText("");
					searchBoxEdit.setInputType(InputType.TYPE_CLASS_TEXT);
				}					
			}
		});		
	}	
	
	private void searchWithString(){
		
		// we can't expect when user edit the source in newSourceView, therefore we have to
		// bring the source whenever search button being clicked
		String searchBoxEditString = searchBoxEdit.getText().toString();
		String newSourceViewString = newSourceView.getText().toString();
		
		// if the searchBoxEdit's string is different from previous result, start from beginning of source					
		if(!(searchBoxEditString.equals(preSearchString))){
			preSearchString	= searchBoxEditString;
			preSearchStart	= newSourceViewString.indexOf(preSearchString);
			preSearchCount	= preSearchString.length();												
			
			// if there's a match, select it										
			if(preSearchStart != -1)
				Selection.setSelection(newSourceView.getText(), preSearchStart, preSearchStart + preSearchCount);
			
			// no match, show a toast message
			else{
				preSearchString	= "";
				Toast toast = Toast.makeText(getContext(), "No matches", Toast.LENGTH_SHORT);
				toast.setGravity(Gravity.TOP, 0, 150);
				toast.show();							
			}
		
		// if the searchBoxEdit's string is same as previous result, starts at next to the previous result
		}else {
			preSearchStart = newSourceViewString.indexOf(preSearchString, preSearchStart + preSearchCount);
			
			// if there's no matches, start again
			if(preSearchStart == -1)
				preSearchStart = newSourceViewString.indexOf(preSearchString);
			
			Selection.setSelection(newSourceView.getText(), preSearchStart , preSearchStart  + preSearchCount);						
		}					
		newSourceView.requestFocus();
	}
	
	private void searchWithLineNumber(){
		String searchBoxEditString = searchBoxEdit.getText().toString();
		
		if(TextUtils.isDigitsOnly(searchBoxEdit.getText())){
			int desireLine = Integer.valueOf(searchBoxEditString) - 1;
			if(desireLine < newSourceView.getLayout().getLineCount() && desireLine > -1){							
				Selection.setSelection(newSourceView.getText(), newSourceView.getLayout().getLineStart(desireLine) , newSourceView.getLayout().getLineStart(desireLine));
				Selection.moveToLeftEdge(newSourceView.getText(), newSourceView.getLayout());
				newSourceView.requestFocus();
			}else{
				Toast toast = Toast.makeText(getContext(), "Line number out of range", Toast.LENGTH_SHORT);
				toast.setGravity(Gravity.TOP, 0, 150);
				toast.show();							
			}
		}
	}
	
	/* get 'iputMethodManager' from activity  */
	public void setInputMethodManager(InputMethodManager imm){
		inputMethodManager = imm;
	}		
}
